1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include <cstdio> #include <vector> #include <cstring> #define LL long long using namespace std; int n, A, B, C, m, p[65]; LL mo, f[65][65][65]; vector <int> sz; LL calc(){ bool vis[65]; memset(vis, 0, sizeof vis); sz.clear(); for (int i = 1; i <= n; i++){ if (vis[i]) continue; int cur = i, t = 0; while (!vis[cur]){ vis[cur] = 1; ++t; cur = p[cur]; } sz.push_back(t); } memset(f, 0, sizeof f); f[0][0][0] = 1; for (int i = 0; i < sz.size(); i++){ for (int a = A; a >= 0; a--) for (int b = B; b >= 0; b--) for (int c = C; c >= 0; c--){ if (A - a >= sz[i]) f[a + sz[i]][b][c] = (f[a + sz[i]][b][c] + f[a][b][c]) % mo; if (B - b >= sz[i]) f[a][b + sz[i]][c] = (f[a][b + sz[i]][c] + f[a][b][c]) % mo; if (C - c >= sz[i]) f[a][b][c + sz[c]] = (f[a][b][c + sz[c]] + f[a][b][c]) % mo; } } return f[A][B][C]; } LL ans = 0; LL pow(LL x, LL t){ LL res = 1; x %= mo; while (t > 0){ if (t & 1) res = res * x % mo; x = x * x % mo; t >>= 1; } return res; } int main(){ scanf("%d%d%d%d%lld", &A, &B, &C, &m, &mo); n = A + B + C; for (int i = 1; i <= m; i++){ for (int j = 1; j <= n; j++) scanf("%d", p + j); ans = (ans + calc()) % mo; } for (int j = 1; j <= n; j++) p[j] = j; ans = (ans + calc()) % mo; printf("%lld\n", ans * pow(m + 1, mo - 2) % mo); return 0; }
|